home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 34.zip / BS1 part 34 / FredFish PD 315.adf / Surf / mapstuff.c < prev    next >
C/C++ Source or Header  |  1990-02-14  |  10KB  |  412 lines

  1. #include <math.h>
  2. #include "mytypes.h"
  3. #include "poly.h"
  4. #include "bezpt.h"
  5. #include "revolve.h"
  6. #include "readilbm.h"
  7. #include "mapstuff.h"
  8. #include "menuexp.h"
  9.  
  10. #define FarRight   1e6
  11. #define FarLeft   -1e6
  12. #define FarTop     0x7fff
  13. #define FarBottom -0x7fff
  14.  
  15.  
  16. #ifndef MANX
  17. #include <libraries/mathffp.h>
  18. #define ceil    SPCeil
  19. #define floor   SPFloor
  20. #define fabs    SPAbs
  21. #endif
  22.  
  23.  
  24. typedef struct { float left, right; } Hedge;
  25.  
  26. static float *BezMapping = null,
  27.              *RevMapping = null;
  28. static float revmin, revdiff,
  29.              bezmin, bezdiff;
  30.  
  31.  
  32. /*
  33.  * given the ptlist of a polygon, find its vertical range
  34.  */
  35. static void FindVRange(scrnlist, top, bottom)
  36.     register ScrnPair *scrnlist;
  37.     short *top, *bottom;
  38. {
  39.     short i;
  40.     short localtop, localbot;
  41.  
  42.     localtop = FarBottom;
  43.     localbot = FarTop;
  44.  
  45.     for( i = 4; i--; scrnlist++ ) {
  46.         if( localtop < scrnlist->y ) localtop = scrnlist->y;
  47.         if( localbot > scrnlist->y ) localbot = scrnlist->y;
  48.     }
  49.     *top = localtop;
  50.     *bottom = localbot;
  51. }
  52. /*
  53.  * allocate table to store a quick and dirty representation of the
  54.  * quadrilateral segments
  55.  */
  56. static Hedge *InitVRange( depth, tabptr, olddepth )
  57.     short depth, *olddepth;
  58.     Hedge *tabptr;
  59. {
  60.     Hedge *edgel, *tab;
  61.     if( *olddepth < depth || !tabptr ) {
  62.         if( tabptr ) free( tabptr);
  63.         tab = (Hedge *) malloc(sizeof(Hedge)*depth);
  64.         *olddepth = depth;
  65.     }
  66.     else {
  67.         tab = tabptr;
  68.     }
  69.     if( !tab ) return( null);
  70.  
  71.     for( edgel = tab; depth--; edgel++) {
  72.         edgel->left = FarRight;
  73.         edgel->right = FarLeft;
  74.     }
  75.     return( tab );
  76. }
  77.  
  78.  
  79. /*
  80.  * add line to quadrilateral descriptions
  81.  */
  82. static void AddVLine( tab, x1, y1, x2, y2 )
  83.     Hedge *tab;
  84.     short x1, y1, x2, y2;
  85. {
  86.     short dy;
  87.     float curx, slope;
  88.     /*
  89.      * want y1 to have smaller value, ie, y1 below y2
  90.      */
  91.     if( y1 > y2 ) {
  92.         short temp;
  93.         temp = y1; y1 = y2; y2 = temp;
  94.         temp = x1; x1 = x2; x2 = temp;
  95.     }
  96.     dy = y2 - y1;
  97.     tab += y1;
  98.  
  99.     if( !dy ) {
  100.         if ( x1 < x2 ) {
  101.             short tempx;
  102.             tempx = x1; x1 = x2; x2 = tempx;
  103.         }
  104.         if( x2 < tab->left ) tab->left = x2;
  105.         if( x1 > tab->right ) tab->right = x1;
  106.         return;
  107.     }
  108.     slope = (float)(x2 - x1)/dy;
  109.  
  110.     curx = x1;
  111. #define ZipIt(xxx) { if( xxx < tab->left) tab->left = xxx; \
  112.                      if( xxx > tab->right ) tab->right = xxx; }
  113.     ZipIt(curx);
  114.     while( dy--) {
  115.         curx += slope;
  116.         tab++;
  117.         ZipIt(curx);
  118.     }
  119. }
  120.  
  121.  
  122. static void AdjMapXY( inx, iny, outpair)
  123.     float inx, iny;
  124.     ScrnPair *outpair;
  125. {
  126.     float outx, outy;
  127.     MapXYRatio( inx, iny, &outx, &outy);
  128.  
  129.     outpair->y = MapImageH * (bezmin + bezdiff * outy);
  130.     outpair->x = MapImageV * (revmin + revdiff * outx);
  131.  
  132. /*
  133.     if( RevAxis == RevX ) {
  134.         outpair->y = MapImageH * (bezmin + bezdiff * outy);
  135.         outpair->x = MapImageV * (revmin + revdiff * outx);
  136.     } else {
  137.         outpair->x = MapImageH * (bezmin + bezdiff * outy);
  138.         outpair->y = MapImageV * (revmin + revdiff * outx);
  139.     }
  140.  */
  141. }
  142.  
  143. static void ScanCnvQuad( tab, pt)
  144.     Hedge *tab;
  145.     ScrnPair pt[];
  146. {
  147.     register int i;
  148.     ScrnPair *listb, *liste;
  149.  
  150.     liste = pt;
  151.     listb = liste + 3;
  152.     for ( i = 4; i--;) {
  153.         AddVLine( tab, listb->x, listb->y, liste->x, liste->y);
  154.         listb = liste++;
  155.     }
  156. }
  157.  
  158. static float AverageShade(pts)
  159.     ScrnPair pts[];
  160. {
  161.     register Hedge *tab;
  162.     static Hedge *tabfree = null;
  163.     static short olddepth = 0;
  164.     short top, bot;
  165.     long shade = 0,
  166.          pixcnt = 0;
  167.  
  168.     FindVRange( pts, &top, &bot);
  169.     tabfree = tab = InitVRange( top - bot + 1, tabfree, &olddepth);
  170.     if(!tabfree) return(0.0);
  171.  
  172.     ScanCnvQuad( tab-bot, pts );
  173. #if DEBUG
  174.     if( DebugOn ) {
  175.         printf("AverageShade top is %d, bot = %d\n", top, bot );
  176.     }
  177. #endif DEBUG
  178.  
  179.     while( bot <= top ) {
  180.         register int hori;
  181.         int right, left;
  182. #if DEBUG
  183.     if( DebugOn ) {
  184.         printf("....row %d    \t%d -> %d\n", bot, left, right );
  185.     }
  186. #endif DEBUG
  187.  
  188.         left =  (int) ceil(tab->left - SingleTinyVal);
  189.         right = (int)floor(tab->right+ SingleTinyVal);
  190.  
  191.         for( hori= left; hori <= right; hori++ ) {
  192.             shade += GetImgPix( bot, hori);
  193.             pixcnt++;
  194.         }
  195.  
  196.     /*
  197.         if( RevAxis == RevX ) {
  198.             for( hori= left; hori <= right; hori++ ) {
  199.                 shade += GetImgPix( bot, hori);
  200.                 pixcnt++;
  201.             }
  202.         }
  203.         else {
  204.             for( hori= left; hori <= right; hori++ ) {
  205.                 shade += GetImgPix( hori, bot);
  206.                 pixcnt++;
  207.             }
  208.         }
  209.     */
  210.         tab++;
  211.         bot++;
  212.     }
  213.     return( (float)shade / (pixcnt *(15 *16)) );
  214. }
  215.  
  216. /*
  217.  * mess with the number so truncation doesn't
  218.  * do nasty things to a float containing an int
  219.  */
  220. static int NearestInt( afloat )
  221.     float afloat;
  222. {
  223.     afloat += ( afloat > 0 )? 1e-2 : -1e-2;
  224.     return( (int)afloat );
  225. }
  226.  
  227.  
  228. static void ShadeQuad(tab, top, bot, intensity)
  229.     register Hedge *tab;
  230.     short top, bot;
  231.     float intensity;
  232. {
  233.     short vert;
  234.     float rowminl, rowminr,
  235.           rowmaxl, rowmaxr;
  236.     Hedge *oldtab, *nexttab;
  237.  
  238.     for ( vert =  bot;
  239.         nexttab = tab+1, vert <= top;
  240.         vert++, oldtab = tab, tab++ ) {
  241.         float hori;
  242.         float colmin, colmax;
  243.         float leftmost, rightmost;
  244.         int ihori, ileftmost, irightmost;
  245.         ScrnPair MpPnts[4];
  246.  
  247. #define lefttop MpPnts[0]
  248. #define leftbot MpPnts[3]
  249. #define righttop MpPnts[1]
  250. #define rightbot MpPnts[2]
  251.  
  252.  
  253.         rowminl = (float)vert;
  254.         rowmaxr = rowmaxl = rowminr = rowminl;
  255.  
  256.         if( vert > bot && oldtab->left < tab->left ) {
  257.             rowminl -= 0.5;
  258.         }
  259.         if( vert > bot && oldtab->right > tab->right ) {
  260.             rowminr -= 0.5;
  261.         }
  262.         if( vert < top && nexttab->left < tab->left ) {
  263.             rowmaxl += 0.5;
  264.         }
  265.         if( vert < top && nexttab->right > tab->right ) {
  266.             rowmaxr += 0.5;
  267.         }
  268.  
  269.         irightmost = NearestInt( tab->right );
  270.         rightmost = irightmost;
  271.         ileftmost = NearestInt( tab->left );
  272.         leftmost = ileftmost;
  273.         if( irightmost < ileftmost ) {
  274.             irightmost = ileftmost;
  275.         }
  276.         for( ihori = leftmost, hori = leftmost;
  277.             ihori <= irightmost;
  278.             ihori += 1, hori += 1.0 ) {
  279.  
  280.  
  281.             if( AbortDraw ) { return; }
  282.  
  283.             colmin = hori - 0.5;
  284.             colmax = hori + 0.5;
  285.  
  286.             colmin =(colmin > leftmost)?colmin: tab->left;
  287.             colmax =(colmax < rightmost)?colmax: tab->right;
  288.  
  289.             AdjMapXY( colmin, rowmaxl, &lefttop,  MP_XMIN| MP_YMAX);
  290.             AdjMapXY( colmax, rowmaxr, &righttop, MP_XMAX| MP_YMAX);
  291.             AdjMapXY( colmin, rowminl, &leftbot,  MP_XMIN| MP_YMIN);
  292.             AdjMapXY( colmax, rowminr, &rightbot, MP_XMAX| MP_YMIN);
  293.  
  294.             PaintPoint(ihori, vert, AverageShade(MpPnts) *intensity);
  295.         }
  296.     }
  297. #undef lefttop
  298. #undef righttop
  299. #undef rightbot
  300. #undef leftbot
  301. }
  302.  
  303.  
  304. void DrawRhomMap(mpr)
  305.     MapRhomboid *mpr;
  306. {
  307.     short top, bottom;
  308.     static Hedge *tab = null;
  309.     static short olddepth = 0;
  310.  
  311.     CalcMapConsts( mpr->rhom.pt );
  312.     FindVRange( mpr->rhom.pt, &top, &bottom );
  313.     tab = InitVRange( top - bottom + 1, tab, &olddepth );
  314.     if(!tab) return;
  315.     ScanCnvQuad( tab -bottom, mpr->rhom.pt );
  316.  
  317.     bezmin = BezMapping[mpr->bezindex];/* make it global */
  318.     bezdiff = BezMapping[mpr->bezindex+1] - bezmin;
  319.     revmin = RevMapping[mpr->revindex];
  320.     revdiff = RevMapping[mpr->revindex+1] - revmin;
  321. #if DEBUG
  322.     if( DebugOn ) {
  323.         DBMAP(mpr->rhom.pt, mpr->bezindex, mpr->revindex);
  324.     }
  325. #endif DEBUG
  326.     ShadeQuad(tab, top, bottom, mpr->rhom.intensity);
  327. }
  328.  
  329. #ifdef DEBUG
  330. DBMAP(ptlist, bindex, rindex)
  331. ScrnPair ptlist[];
  332. short bindex, rindex;
  333. {
  334.     int i;
  335.  
  336.     printf("...................................\n");
  337.     for( i = 0; i < 4; i++ ) {
  338.         printf("%10d", ptlist[i].x);
  339.     };
  340.     printf("\n");
  341.     for( i = 0; i < 4; i++ ) {
  342.         printf("%10d", ptlist[i].y);
  343.     };
  344.     printf("\n");
  345.     printf(" bezmin %f  bezdiff %f index = %d \n", bezmin, bezdiff, bindex );
  346.     printf(" revmin %f  revdiff %f index = %d \n", revmin, revdiff, rindex );
  347. }
  348. #endif DEBUG
  349.  
  350.  
  351. /*
  352.  * return true if image mappings could not be performed
  353.  * false if successful
  354.  */
  355. bool InitMapping() {
  356.     float *vfmptr;
  357.     float totallen = 0,
  358.           scaling;
  359.     short numvslices;
  360.  
  361.     if( BezMapping ) free( BezMapping );
  362.     if( RevMapping ) free( RevMapping );
  363.  
  364.     /*
  365.      * compute width of each bezier segment
  366.      */
  367.     numvslices = BezMesh*GetNumSegs() +1;
  368.     vfmptr = BezMapping = (float *) malloc(sizeof(float) * numvslices);
  369.     if( !BezMapping ) return(true);
  370.  
  371.     *vfmptr++ = totallen = 0.0;
  372.     ResetActSeg();
  373.     do {
  374.         float t, ffromx, ftox, ffromy, ftoy;
  375.         int i;
  376.         InitCalcBez();
  377.         for( i = 1, ffromx = StartPtX(ActSeg), ffromy = StartPtY(ActSeg);
  378.             i <= BezMesh; i++, ffromx = ftox, ffromy = ftoy ) {
  379.             float diffx, diffy;
  380.  
  381.             t = (float)i/BezMesh;
  382.  
  383.             CalcBezPt( t, &ftox, &ftoy );
  384.             diffx = ftox - ffromx;
  385.             diffy = ftoy - ffromy;
  386.             totallen += sqrt( diffx * diffx + diffy * diffy );
  387.             *vfmptr++ = totallen;
  388.         }
  389.         NextSeg();
  390.     } while( ActSeg);
  391.     /*
  392.      * convert scale floating point values to integer pixel positions
  393.      */
  394.     scaling = 1.0 / totallen;
  395.     for( vfmptr = BezMapping; numvslices; numvslices--, vfmptr++ ) {
  396.         *vfmptr *= scaling;
  397.     }
  398.     /*
  399.      * compute height of each revolution segment
  400.      */
  401.     RevMapping = (float *) malloc( sizeof(float) * (RevMesh + 1));
  402.     if( !RevMapping ) return( true );
  403.     {
  404.         short i;
  405.         for( i = 0; i <= RevMesh; i++ ) {
  406.             RevMapping[i] =  ((float) i)/RevMesh;
  407.         }
  408.     }
  409.  
  410.     return(false);
  411. }
  412.